﻿
/*============== simpleIRC - http://matthias.van-eeghem.com/ ==============*
 *                                                                         *
 *  File: ConnectWindow.xaml.cs                                            *
 *  Project: simpleIRC                                                     *
 *  Author(s): Matthias Van Eeghem <matthias@van-eeghem.com>               *
 *                                                                         *
 * ========================================================================*
 *                                                                         *
 *  This program is free software: you can redistribute it and/or modify   *
 *  it under the terms of the GNU General Public License as published by   *
 *  the Free Software Foundation, either version 3 of the License, or      *
 *  (at your option) any later version.                                    *
 *                                                                         *
 *  This program is distributed in the hope that it will be useful,        *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
 *  GNU General Public License for more details.                           *
 *                                                                         *
 *  You should have received a copy of the GNU General Public License      *
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
 *                                                                         *
===========================================================================*/

using System;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;

namespace simpleIRC.UI
{
    /// <summary>
    /// Interaction logic for ConnectWindow.xaml
    /// </summary>

    public partial class OptionsWindow : Window
    {
        private MainWindow mainWindow = null;
        private UserInterface UserInterface = null;

        /// <summary>
        /// The constructor of the ConnectWindow class
        /// </summary>
        /// <param name="parentWindow">The reference to the mainWindow object</param>

        public OptionsWindow(MainWindow parentWindow)
        {
            // Initialise the visual components of the connect window form.
            InitializeComponent();

            mainWindow = parentWindow;
            UserInterface = new UserInterface(parentWindow);

            // Set the timestamp message box
            TimestampMessagebox.Text = mainWindow.Config.Settings["Timestamp"];
            string SortChannelsChecked = mainWindow.Config.Settings["SortChannels"];

            if (SortChannelsChecked == "true")
            {
                checkBoxSortChannels.IsChecked = true;
            }
            else checkBoxSortChannels.IsChecked = false;

            // Loop through the plugin list
            foreach (string PluginName in mainWindow.PluginNames)
            {
                // Add the item to the treeview
                PluginList.Items.Add(PluginName);

                // Create a new context menu.
                ContextMenu RightClickMenu = new ContextMenu();

                // Create a new menu item.
                MenuItem MenuItem = new MenuItem();
                MenuItem.Header = "Unload";
                MenuItem.Click += new RoutedEventHandler(ContextMenu_UnloadPlugin);

                // Save the context menu
                PluginList.ContextMenu = RightClickMenu;
                PluginList.ContextMenu.Items.Add(MenuItem);
            }
        }

        /// <summary>
        /// This method is called when a user selects Right click -> Unload option menu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void ContextMenu_UnloadPlugin(object sender, EventArgs e)
        {
            // Check if we have an item selected
            if (PluginList.SelectedIndex != -1)
            {
                int SelectedIndex = PluginList.SelectedIndex;

                mainWindow.PluginList[SelectedIndex].OnPluginUnload();

                // Remove the plugin from the pluginlists
                mainWindow.PluginList.RemoveAt(SelectedIndex);
                mainWindow.PluginNames.RemoveAt(SelectedIndex);

                // Remove the plugin from the list in the OptionWindow
                PluginList.Items.RemoveAt(SelectedIndex);
            }
        }

        /// <summary>
        /// Called when the main form is closed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // If the window gets closed, we want to set the variable of the connectWindow instance to null.
            mainWindow.OptionsWindow = null;
        }

        /// <summary>
        /// This function saves all changed values to the configuration
        /// </summary>

        private void SaveToConfig()
        {
            mainWindow.Config.SetConfigValue("Timestamp", TimestampMessagebox.Text);
            mainWindow.Config.SetConfigValue("SortChannels", checkBoxSortChannels.IsChecked.ToString().ToLower());
        }

        /// <summary>
        /// This method gets called when a user clicks the select button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void buttonSelect_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog selectFile = new OpenFileDialog();
            selectFile.Filter = "DLL files (*.dll)|*.dll";
            selectFile.Title = "Select a plugin";
            selectFile.ShowDialog();

            if (selectFile.FileName != "")
            {
                try
                {
                    Assembly DllAssembly = Assembly.LoadFile(selectFile.FileName);

                    foreach (Type AsmType in DllAssembly.GetTypes())
                    {
                        // Make sure it's the correct interface
                        if (AsmType.GetInterface("PluginInterface") != null)
                        {
                            // Get the index of the last \
                            int StartIndex = selectFile.FileName.LastIndexOf('\\');

                            // Get the substring from the last index of the \ to the end
                            string FileWithoutDirectory = selectFile.FileName.ToString().Substring(StartIndex + 1);

                            bool FileAlreadyFound = false;

                            // Check if a plugin with that name is already loaded
                            foreach (string FileName in mainWindow.PluginNames) if (FileWithoutDirectory == FileName) FileAlreadyFound = true;

                            if (!FileAlreadyFound)
                            {
                                // Create a new instance of the plugin
                                PluginInterface Plugin = (PluginInterface)Activator.CreateInstance(AsmType);

                                Plugin.OnBasePluginLoad(mainWindow);

                                mainWindow.PluginList.Add(Plugin);
                                PluginList.Items.Add(FileWithoutDirectory);

                                MenuItem MenuItem = new MenuItem();
                                MenuItem.Header = "Unload";
                                MenuItem.Click += new RoutedEventHandler(ContextMenu_UnloadPlugin);

                                ContextMenu RightClickMenu = new ContextMenu();
                                PluginList.ContextMenu = RightClickMenu;
                                PluginList.ContextMenu.Items.Add(MenuItem);

                                // Add the plugin name to the plugin name list
                                mainWindow.PluginNames.Add(FileWithoutDirectory);
                            }
                            else
                            {
                                MessageBox.Show("There is already a plugin found with that name.", "Failed to load plugin", MessageBoxButton.OK, MessageBoxImage.Error);
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    MessageBox.Show("Failed to load " + selectFile.FileName, "Failed to load plugin", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        /// <summary>
        /// Called when a user hits the OK button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void btnOK_Click(object sender, RoutedEventArgs e)
        {
            SaveToConfig();
            mainWindow.Config.LoadConfig();
            Close();
        }

        /// <summary>
        /// Called when a user hits the Check for updates button in the Updates tab
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void btnCheckForUpdates_Click(object sender, RoutedEventArgs e)
        {
            new System.Threading.Thread(() => { new Update(mainWindow).CheckForUpdates(); }).Start();
        }

        /// <summary>
        /// Called when a user hits the Close button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }
    }
}
